home *** CD-ROM | disk | FTP | other *** search
- {*******************************************************}
- { }
- { ActiveX Document Support Unit }
- { Copyright (c) 1999, Steve Teixeira }
- { }
- {*******************************************************}
-
- unit AxDocs;
-
- interface
-
- uses
- Windows, ComObj, ActiveX, AxCtrls, Controls;
-
- type
- TActiveXDocument = class(TActiveXControl, IOleDocument, IOleDocumentView)
- private
- function GetAncestorValueByField(FieldNum: Cardinal): Cardinal;
- procedure SetAncestorValueByField(FieldNum, Value: Cardinal);
- function GetOleInPlaceSite: IOleInPlaceSite;
- procedure SetOleInPlaceSite(const Value: IOleInPlaceSite);
- protected
- { IOleDocument methods }
- function CreateView(Site: IOleInPlaceSite; Stream: IStream; rsrvd: DWORD;
- out View: IOleDocumentView):HResult; stdcall;
- function GetDocMiscStatus(var Status: DWORD):HResult; stdcall;
- function EnumViews(out Enum: IEnumOleDocumentViews;
- out View: IOleDocumentView):HResult; stdcall;
- { IOleDocumentView methods }
- function SetInPlaceSite(Site: IOleInPlaceSite):HResult; stdcall;
- function GetInPlaceSite(out Site: IOleInPlaceSite):HResult; stdcall;
- function GetDocument(out P: IUnknown):HResult; stdcall;
- function SetRect(const View: TRECT):HResult; stdcall;
- function GetRect(var View: TRECT):HResult; stdcall;
- function SetRectComplex(const View, HScroll, VScroll, SizeBox):HResult; stdcall;
- function Show(fShow: BOOL):HResult; stdcall;
- function UIActivate(fUIActivate: BOOL):HResult; stdcall;
- function Open:HResult; stdcall;
- function CloseView(dwReserved: DWORD):HResult; stdcall;
- function SaveViewState(pstm: IStream):HResult; stdcall;
- function ApplyViewState(pstm: IStream):HResult; stdcall;
- function Clone(NewSite: IOleInPlaceSite; out NewView: IOleDocumentView):HResult; stdcall;
- public
- function ObjQueryInterface(const IID: TGUID; out Obj): HResult; override;
- property OleInPlaceSite: IOleInPlaceSite read GetOleInPlaceSite write SetOleInPlaceSite;
- end;
-
- TActiveXDocClass = class of TActiveXDocument;
-
- TActiveXDocumentFactory = class(TActiveXControlFactory)
- constructor Create(ComServer: TComServerObject;
- ActiveXDocClass: TActiveXDocClass; WinControlClass: TWinControlClass;
- const ClassID: TGUID; ToolboxBitmapID, MiscStatus: Integer;
- ThreadingModel: TThreadingModel);
- procedure UpdateRegistry(Register: Boolean); override;
- end;
-
- implementation
-
- uses ComServ;
-
- { TActiveXDocument }
-
- function TActiveXDocument.ObjQueryInterface(const IID: TGUID; out Obj): HResult;
- begin
- // Must stub out IOleLink, or container will assume this is a linked object
- // rather than an embedded object.
- if IsEqualGuid(IID, IOleLink) then Result := E_NOINTERFACE
- else Result := inherited ObjQueryInterface(IID, Obj);
- end;
-
- function TActiveXDocument.GetOleInPlaceSite: IOleInPlaceSite;
- begin
- // Work around fact that FOleInPlaceSite is private in TActiveXControl
- // Note: this work around only guaranteed to work in Delphi 4
- Result := IOleInPlaceSite(GetAncestorValueByField(9));
- end;
-
- procedure TActiveXDocument.SetOleInPlaceSite(const Value: IOleInPlaceSite);
- begin
- // Work around fact that FOleInPlaceSite is private in TActiveXControl
- // Note: this work around only guaranteed to work in Delphi 4
- SetAncestorValueByField(9, Cardinal(Value));
- end;
-
- function TActiveXDocument.GetAncestorValueByField(FieldNum: Cardinal): Cardinal;
- var
- ParentInstanceSize, Ofs: Cardinal;
- begin
- // Nasty hack: this method returns the value of a particular field in the
- // ancestor class, with the assumption that the given field and all prior
- // fields are 4 bytes in size.
- ParentInstanceSize := ClassParent.ClassParent.InstanceSize;
- Ofs := ParentInstanceSize + ((FieldNum - 1) * 4);
- asm
- mov eax, Self
- add eax, Ofs
- mov eax, dword ptr [eax]
- mov @Result, eax
- end;
- end;
-
- procedure TActiveXDocument.SetAncestorValueByField(FieldNum, Value: Cardinal);
- var
- ParentInstanceSize, Ofs: Cardinal;
- begin
- // Nasty hack: this method sets the value of a particular field in the
- // ancestor class, with the assumption that the given field and all prior
- // fields are 4 bytes in size.
- ParentInstanceSize := ClassParent.ClassParent.InstanceSize;
- Ofs := ParentInstanceSize + ((FieldNum - 1) * 4);
- asm
- mov eax, Self
- add eax, Ofs
- mov ecx, Value
- mov dword ptr [eax], ecx
- end;
- end;
-
- { TActiveXDocument.IOleDocument }
-
- function TActiveXDocument.CreateView(Site: IOleInPlaceSite;
- Stream: IStream; rsrvd: DWORD; out View: IOleDocumentView): HResult;
- var
- OleDocView: IOleDocumentView;
- begin
- Result := S_OK;
- try
- if View = nil then
- begin
- Result := E_POINTER;
- Exit;
- end;
- OleDocView := Self as IOleDocumentView;
- if (OleInPlaceSite = nil) or (OleDocView = nil) then
- begin
- Result := E_FAIL;
- Exit;
- end;
- // Use site provided
- if Site <> nil then OleDocView.SetInPlaceSite(Site);
- // Use stream provided for initialization
- if Stream <> nil then OleDocView.ApplyViewState(Stream);
- // Return the view
- View := OleDocView;
- except
- Result := E_FAIL;
- end;
- end;
-
- function TActiveXDocument.EnumViews(out Enum: IEnumOleDocumentViews;
- out View: IOleDocumentView): HResult;
- begin
- Result := S_OK;
- try
- // We only support one view
- View := Self as IOleDocumentView;
- except
- Result := E_FAIL;
- end;
- end;
-
- function TActiveXDocument.GetDocMiscStatus(var Status: DWORD): HResult;
- begin
- Status := 8 {DOCMISC_NOFILESUPPORT};
- Result := S_OK;
- end;
-
- { TActiveXDocument.IOleDocument }
-
- function TActiveXDocument.ApplyViewState(pstm: IStream): HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TActiveXDocument.Clone(NewSite: IOleInPlaceSite;
- out NewView: IOleDocumentView): HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TActiveXDocument.CloseView(dwReserved: DWORD): HResult;
- begin
- Result := S_OK;
- try
- Show(False);
- SetInPlaceSite(nil);
- except
- Result := E_UNEXPECTED;
- end;
- end;
-
- function TActiveXDocument.GetDocument(out P: IUnknown): HResult;
- begin
- Result := S_OK;
- try
- P := Self as IUnknown;
- except
- Result := E_FAIL;
- end;
- end;
-
- function TActiveXDocument.GetInPlaceSite(out Site: IOleInPlaceSite): HResult;
- begin
- Result := S_OK;
- try
- Site := OleInPlaceSite;
- except
- Result := E_FAIL;
- end;
- end;
-
- function TActiveXDocument.GetRect(var View: TRECT): HResult;
- begin
- Result := S_OK;
- try
- View := Control.BoundsRect;
- except
- Result := E_UNEXPECTED;
- end;
- end;
-
- function TActiveXDocument.Open: HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TActiveXDocument.SaveViewState(pstm: IStream): HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TActiveXDocument.SetInPlaceSite(Site: IOleInPlaceSite): HResult;
- begin
- Result := S_OK;
- try
- if OleInPlaceSite <> nil then
- Result := InPlaceDeactivate;
- if Result <> S_OK then Exit;
- if Site <> nil then OleInPlaceSite := Site;
- except
- Result := E_UNEXPECTED;
- end;
- end;
-
- function TActiveXDocument.SetRect(const View: TRECT): HResult;
- begin
- // Implement using TActiveXControl's IOleInPlaceObject.SetObjectRects impl
- Result := SetObjectRects(View, View);
- end;
-
- function TActiveXDocument.SetRectComplex(const View; const HScroll;
- const VScroll; const SizeBox): HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TActiveXDocument.Show(fShow: BOOL): HResult;
- begin
- try
- if fShow then
- Result := InPlaceActivate(False)
- else begin
- Result := UIActivate(False);
- Control.Visible := False;
- end;
- except
- Result := E_UNEXPECTED;
- end;
- end;
-
- function TActiveXDocument.UIActivate(fUIActivate: BOOL): HResult;
- begin
- Result := S_OK;
- try
- if FUIActivate then
- begin
- if OleInPlaceSite <> nil then InPlaceActivate(True)
- else Result := E_UNEXPECTED;
- end
- else
- UIDeactivate;
- except
- Result := E_UNEXPECTED;
- end;
- end;
-
- { TActiveXDocumentFactory }
-
- constructor TActiveXDocumentFactory.Create(ComServer: TComServerObject;
- ActiveXDocClass: TActiveXDocClass; WinControlClass: TWinControlClass;
- const ClassID: TGUID; ToolboxBitmapID, MiscStatus: Integer;
- ThreadingModel: TThreadingModel);
- begin
- inherited Create(ComServer, ActiveXDocClass, WinControlClass, ClassId,
- ToolboxBitmapID, '', MiscStatus, ThreadingModel);
- end;
-
- procedure TActiveXDocumentFactory.UpdateRegistry(Register: Boolean);
- var
- ClassKey: string;
- begin
- ClassKey := 'CLSID\' + GUIDToString(ClassID) + '\';
- if Register then
- begin
- inherited UpdateRegistry(Register);
- CreateRegKey(ClassKey + 'DocObject', '', '8');
- CreateRegKey(ClassKey + 'Programmable', '', '');
- CreateRegKey(ClassKey + 'Insertable', '', '');
- end
- else begin
- DeleteRegKey('DocObject');
- DeleteRegKey('Programmable');
- DeleteRegKey('Insertable');
- inherited UpdateRegistry(Register);
- end;
- end;
-
- end.
-